﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using DataTier.Entities;
using DataTier.Helpers;

namespace DataTier.Repository
{
    /// <summary>
    /// Репозиторий для работы со словарями системы
    /// </summary>
    public class DictionariesRepository : RepositoryBase
    {
        public DictionariesRepository()
        {

        }

        public DictionariesRepository(IDbConnection connection)
            : base(connection)
        {

        }

        #region Методы работы с сущностью Отдел

        /// <summary>
        /// Возвращает список отделов
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<DepartmentEntity> GetDepartmentList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.Department.Where(d => d.Deleted != true).ToList();
                return list.Select(d => EntityHelper.GetDepartmentEntity(d)).ToList();
            }
        }

        /// <summary>
        /// Сохранение Отдела
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="department"></param>
        /// <returns></returns>
        public int SaveDepartment(int currentUserId, DepartmentEntity department)
        {
            using (var dbcontext = CreateDataContext())
            {
                int departmentId = 0;
                Department savedDepartment = null;
                if (department.DepartmentId > 0) // Если происходит обновление уже существующей записи об Отделе в БД
                {
                    var dep = dbcontext.Department.Where(d => d.DepartmentId == department.DepartmentId).FirstOrDefault();
                    if (dep != null)
                    {
                        savedDepartment = dep;
                        if (department.JuridicalPersonId != null && department.JuridicalPersonId > 0)
                        {
                            var jur = dbcontext.JuridicalPerson.Where(j => j.JuridicalPersonId == department.JuridicalPersonId).FirstOrDefault();
                            if (jur != null)
                                savedDepartment.JuridicalPerson = jur;
                        }

                        savedDepartment.Name = department.Name;
                        savedDepartment.OfficeNumber = department.OfficeNumber;
                        if (department.Deleted != null && department.Deleted.Value == true)
                            savedDepartment.Deleted = department.Deleted.Value;
                    }
                    else // Отдел создается
                    {
                        #region // Отдел создается

                        savedDepartment = new Department()
                        {
                            Name = department.Name,
                            OfficeNumber = department.OfficeNumber
                        };

                        if (department.JuridicalPersonId != null && department.JuridicalPersonId > 0)
                        {
                            var jur = dbcontext.JuridicalPerson.Where(j => j.JuridicalPersonId == department.JuridicalPersonId).FirstOrDefault();
                            if (jur != null)
                                savedDepartment.JuridicalPerson = jur;
                        }

                        #endregion // Отдел создается
                    }
                }
                else // Если Отдел создается
                {
                    #region // Если Отдел создается

                    int newid = dbcontext.Department.Select(j => j.DepartmentId).Max() + 1;
                    savedDepartment = new Department()
                    {
                        DepartmentId = newid,
                        Name = department.Name,
                        OfficeNumber = department.OfficeNumber
                    };

                    if (department.JuridicalPersonId != null && department.JuridicalPersonId > 0)
                    {
                        var jur = dbcontext.JuridicalPerson.Where(j => j.JuridicalPersonId == department.JuridicalPersonId).FirstOrDefault();
                        if (jur != null)
                            savedDepartment.JuridicalPerson = jur;
                    }

                    dbcontext.AddToDepartment(savedDepartment);
                    
                    #endregion // Если Отдел создается
                }

                dbcontext.SaveChanges();

                departmentId = savedDepartment.DepartmentId;

                return departmentId;
            }
        }

        /// <summary>
        /// Удаление Отдела
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="departmentId"></param>
        public void DeleteDepartment(int currentUserId, int departmentId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var department = dbcontext.Department.Where(d => d.DepartmentId == departmentId).FirstOrDefault();
                if (department != null)
                {
                    department.Deleted = true;
                    dbcontext.SaveChanges();
                }
            }
        }

        #endregion Методы работы с сущностью Отдел

        #region Методы работы с сущностью Компания

        /// <summary>
        /// Возвращает список Компаний
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<Company> GetCompanyList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.Company.Where(c => c.Deleted != true).ToList();
                return list.ToList();
            }
        }

        #endregion Методы работы с сущностью Компания

        #region Методы работы с сущностью Юридическое лицо

        /// <summary>
        /// Возвращает список Юридических лиц
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<JuridicalPersonEntity> GetJuridicalPersonList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.JuridicalPerson.Where(j => j.Deleted != true).ToList();
                return list.Select(j => EntityHelper.GetJuridicalPersonEntity(j)).ToList();
            }
        }

        /// <summary>
        /// Сохранение Юридического лица
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="juridicalPerson"></param>
        /// <returns></returns>
        public int SaveJuridicalPerson(int currentUserId, JuridicalPersonEntity juridicalPerson)
        {
            using (var dbcontext = CreateDataContext())
            {
                int juridicalPersonId = 0;
                JuridicalPerson savedJuridicalPerson = null;
                if (juridicalPerson.JuridicalPersonId > 0) // Если происходит обновление уже существующей записи о Юридическом лице в БД
                {
                    var jur = dbcontext.JuridicalPerson.Where(j => j.JuridicalPersonId == juridicalPerson.JuridicalPersonId).FirstOrDefault();
                    if (jur != null)
                    {
                        savedJuridicalPerson = jur;
                        if (juridicalPerson.CompanyId != null && juridicalPerson.CompanyId > 0)
                        {
                            var comp = dbcontext.Company.Where(c => c.CompanyId == juridicalPerson.CompanyId).FirstOrDefault();
                            if (comp != null)
                                savedJuridicalPerson.Company = comp;
                        }

                        savedJuridicalPerson.Name = juridicalPerson.Name;
                        savedJuridicalPerson.ManagerEMail = juridicalPerson.ManagerEMail;
                        if (juridicalPerson.Deleted != null && juridicalPerson.Deleted.Value == true)
                            savedJuridicalPerson.Deleted = juridicalPerson.Deleted.Value;
                    }
                    else // Юридическое лицо создается
                    {
                        #region // Юридическое лицо создается

                        savedJuridicalPerson = new JuridicalPerson()
                        {
                            Name = juridicalPerson.Name,
                            ManagerEMail = juridicalPerson.ManagerEMail
                        };

                        if (juridicalPerson.CompanyId != null && juridicalPerson.CompanyId > 0)
                        {
                            var comp = dbcontext.Company.Where(c => c.CompanyId == juridicalPerson.CompanyId).FirstOrDefault();
                            if (comp != null)
                                savedJuridicalPerson.Company = comp;
                        }

                        dbcontext.AddToJuridicalPerson(savedJuridicalPerson);

                        #endregion // Юридическое лицо создается
                    }
                }
                else // Если Юридическое лицо создается
                {
                    #region // Если Юридическое лицо создается

                    int newid = dbcontext.JuridicalPerson.Select(j => j.JuridicalPersonId).Max() + 1;
                    savedJuridicalPerson = new JuridicalPerson()
                    {
                        JuridicalPersonId = newid,
                        Name = juridicalPerson.Name,
                        ManagerEMail = juridicalPerson.ManagerEMail
                    };

                    if (juridicalPerson.CompanyId != null && juridicalPerson.CompanyId > 0)
                    {
                        var comp = dbcontext.Company.Where(c => c.CompanyId == juridicalPerson.CompanyId).FirstOrDefault();
                        if (comp != null)
                            savedJuridicalPerson.Company = comp;
                    }

                    dbcontext.AddToJuridicalPerson(savedJuridicalPerson);

                    #endregion // Если Юридическое лицо создается
                }

                dbcontext.SaveChanges();

                juridicalPersonId = savedJuridicalPerson.JuridicalPersonId;

                return juridicalPersonId;
            }
        }


        /// <summary>
        /// Удаление Юридического лица
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="RoleId"></param>
        public void DeleteJuridicalPerson(int currentUserId, int juridicalPersonId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var jur = dbcontext.JuridicalPerson.Where(j => j.JuridicalPersonId == juridicalPersonId).FirstOrDefault();
                if (jur != null)
                {
                    jur.Deleted = true;
                    dbcontext.SaveChanges();
                }
            }
        }

        #endregion Методы работы с сущностью Юридическое лицо

        #region Методы работы с сущностью Центр затрат

        /// <summary>
        /// Возвращает список центров затрат
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<CostsCenterEntity> GetCostsCenterList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.CostsCenter.Where(c => c.Deleted != true).ToList();
                return list.Select(c => EntityHelper.GetCostsCenterEntity(c)).ToList();
            }
        }


        /// <summary>
        /// Возвращается список Центров затрат со связанной с ними информацией о пользователе и правах доступа
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<CostsCenterFullInfoEntity> GetCostsCenterFullInfoList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.CostsCenter
                    .Include("Department")
                    .Include("User")

                    // Подключаются таблицы с информацией о роли и правах пользователя
                    .Include("User.Role")
                    .Include("User.Role.Permission")
                    .Include("User.Role.Permission.PermissionCategory")
                    .Include("User.Role.Permission.Menu")
                    .Include("User.Role.Permission.State")
                    .Include("User.Role.Permission.WebPage")
                    .Where(c => c.Deleted != true).ToList();

                return list.Select(c => EntityHelper.GetCostsCenterFullInfoEntity(c)).ToList();
            }
        }


        /// <summary>
        /// Возвращается Центр затрат со связанной с ними информацией о пользователе и правах доступа
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public CostsCenterFullInfoEntity GetCostsCenterFullInfo(int currentUserId, int CostsCenterId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var center = dbcontext.CostsCenter
                    .Include("Department")
                    .Include("User")

                    // Подключаются таблицы с информацией о роли и правах пользователя
                    .Include("User.Role")
                    .Include("User.Role.Permission")
                    .Include("User.Role.Permission.PermissionCategory")
                    .Include("User.Role.Permission.Menu")
                    .Include("User.Role.Permission.State")
                    .Include("User.Role.Permission.WebPage")
                    .Where(c => c.CostsCenterId == CostsCenterId && c.Deleted != true).FirstOrDefault();

                return EntityHelper.GetCostsCenterFullInfoEntity(center);
            }
        }


        /// <summary>
        /// Возвращается Центр затрат со связанной с ними информацией о пользователе и правах доступа
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public CostsCenterFullInfoEntity GetCostsCenterFullInfoByUserId(int currentUserId, int UserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var center = dbcontext.CostsCenter
                    .Include("Department")
                    .Include("User")

                    // Подключаются таблицы с информацией о роли и правах пользователя
                    .Include("User.Role")
                    .Include("User.Role.Permission")
                    .Include("User.Role.Permission.PermissionCategory")
                    .Include("User.Role.Permission.Menu")
                    .Include("User.Role.Permission.State")
                    .Include("User.Role.Permission.WebPage")
                    .Where(c => c.User.FirstOrDefault() != null && c.User.FirstOrDefault().UserId == UserId && c.Deleted != true).FirstOrDefault();

                return EntityHelper.GetCostsCenterFullInfoEntity(center);
            }
        }

        /// <summary>
        /// Сохранение Центра затрат и информации о пользователе и его правах
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="juridicalPerson"></param>
        /// <returns></returns>
        public int SaveCostsCenterFullInfoEntity(int currentUserId, CostsCenterFullInfoEntity center)
        {
            using (var dbcontext = CreateDataContext())
            {
                int costsCenterId = 0;
                CostsCenter savedCostsCenter = null;
                if (center.CostsCenterId > 0) // Если происходит обновление уже существующей записи о Центре затрат в БД
                {
                    var costsCenter = dbcontext.CostsCenter.Where(c => c.CostsCenterId == center.CostsCenterId).FirstOrDefault();
                    if (costsCenter != null)
                    {
                        savedCostsCenter = costsCenter;
                        if (center.DepartmentId != null && center.DepartmentId > 0)
                        {
                            var dep = dbcontext.Department.Where(d => d.DepartmentId == center.DepartmentId).FirstOrDefault();
                            if (dep != null)
                                savedCostsCenter.Department = dep;
                        }

                        #region User

                        // Обновляется User
                        var user = dbcontext.User.Where(u => u.CostsCenterId == center.CostsCenterId).FirstOrDefault();
                        if (user != null)
                        {
                            user.Email = center.UserEmail;
                            user.FIO = center.UserFIO;
                            user.IsEnable = center.UserIsEnable;
                            user.Login = center.UserLogin;
                            user.Phone = center.UserPhone;
                            user.PassHash = (!string.IsNullOrEmpty(center.UserPassHash)) ? center.UserPassHash : null;
                            user.CostsCenter = savedCostsCenter;

                            if (center.UserRole != null && center.UserRole.Role != null)
                            {
                                var role = dbcontext.Role.Where(r => r.Id == center.UserRole.Role.Id).FirstOrDefault();
                                if (role != null)
                                    user.Role = role;
                            }
                        }
                        else // User создается
                        {
                            // Создается User
                            var savedUser = new User()
                            {
                                Email = center.UserEmail,
                                FIO = center.UserFIO,
                                IsEnable = center.UserIsEnable,
                                Login = center.UserLogin,
                                Phone = center.UserPhone,
                                PassHash = (!string.IsNullOrEmpty(center.UserPassHash)) ? center.UserPassHash : null,
                                CostsCenter = savedCostsCenter
                            };

                            if (center.UserRole != null && center.UserRole.Role != null)
                            {
                                var role = dbcontext.Role.Where(r => r.Id == center.UserRole.Role.Id).FirstOrDefault();
                                if (role != null)
                                    savedUser.Role = role;
                            }

                            dbcontext.AddToUser(savedUser);
                        }

                        #endregion User

                        savedCostsCenter.Name = center.Name;
                        if(center.Deleted != null && center.Deleted.Value == true)
                            savedCostsCenter.Deleted = center.Deleted.Value;
                    }
                    else // Центр затрат создается
                    {
                        #region // Центр затрат создается

                        int newid = dbcontext.CostsCenter.Select(c => c.CostsCenterId).Max() + 1;
                        savedCostsCenter = new CostsCenter()
                        {
                            CostsCenterId = newid,
                            Name = center.Name,
                            BS = center.BS,
                            MVZ = center.MVZ
                        };

                        if (center.DepartmentId != null && center.DepartmentId > 0)
                        {
                            var dep = dbcontext.Department.Where(d => d.DepartmentId == center.DepartmentId).FirstOrDefault();
                            if (dep != null)
                                savedCostsCenter.Department = dep;
                        }

                        dbcontext.AddToCostsCenter(savedCostsCenter);

                        #region User

                        // Создается User
                        var savedUser = new User()
                        {
                            Email = center.UserEmail,
                            FIO = center.UserFIO,
                            IsEnable = center.UserIsEnable,
                            Login = center.UserLogin,
                            Phone = center.UserPhone,
                            PassHash = (!string.IsNullOrEmpty(center.UserPassHash)) ? center.UserPassHash : null,
                            CostsCenter = savedCostsCenter
                        };

                        if (center.UserRole != null && center.UserRole.Role != null)
                        {
                            var role = dbcontext.Role.Where(r => r.Id == center.UserRole.Role.Id).FirstOrDefault();
                            if (role != null)
                                savedUser.Role = role;
                        }

                        dbcontext.AddToUser(savedUser);
                        
                        #endregion User

                        #endregion // Центр затрат создается
                    }
                }
                else // Если Центр затрат создается
                {
                    #region // Если Центр затрат создается

                    int newid = dbcontext.CostsCenter.Select(c => c.CostsCenterId).Max() + 1;
                    savedCostsCenter = new CostsCenter()
                    {
                        CostsCenterId = newid,
                        Name = center.Name,
                        BS = center.BS,
                        MVZ = center.MVZ
                    };

                    if (center.DepartmentId != null && center.DepartmentId > 0)
                    {
                        var dep = dbcontext.Department.Where(d => d.DepartmentId == center.DepartmentId).FirstOrDefault();
                        if (dep != null)
                            savedCostsCenter.Department = dep;
                    }

                    dbcontext.AddToCostsCenter(savedCostsCenter);

                    #region User

                    // Создается User
                    var savedUser = new User()
                    {
                        Email = center.UserEmail,
                        FIO = center.UserFIO,
                        IsEnable = center.UserIsEnable,
                        Login = center.UserLogin,
                        Phone = center.UserPhone,
                        PassHash = (!string.IsNullOrEmpty(center.UserPassHash)) ? center.UserPassHash : null,
                        CostsCenter = savedCostsCenter
                    };

                    if (center.UserRole != null && center.UserRole.Role != null)
                    {
                        var role = dbcontext.Role.Where(r => r.Id == center.UserRole.Role.Id).FirstOrDefault();
                        if (role != null)
                            savedUser.Role = role;
                    }

                    dbcontext.AddToUser(savedUser);

                    #endregion User

                    #endregion // Если Центр затрат создается
                }

                dbcontext.SaveChanges();

                costsCenterId = savedCostsCenter.CostsCenterId;

                return costsCenterId;
            }
        }


        /// <summary>
        /// Удаление Центра затрат
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="CostsCenterId"></param>
        public void DeleteCostsCenter(int currentUserId, int CostsCenterId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var center = dbcontext.CostsCenter.Where(c => c.CostsCenterId == CostsCenterId).FirstOrDefault();
                if (center != null)
                {
                    center.Deleted = true;
                    //dbcontext.CostsCenter.DeleteObject(center);

                    var users = dbcontext.User.Where(u => u.CostsCenterId == CostsCenterId).ToList();
                    if (users != null && users.Count > 0)
                        foreach (var user in users)
                            user.Deleted = true;

                    dbcontext.SaveChanges();
                }
            }
        }

        #endregion Методы работы с сущностью Центр затрат

        #region Методы работы с объектами, относящимися к правам доступа

        /// <summary>
        /// Возвращает список Ролей
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<RoleEntity> GetRoleEntityList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.Role.Where(r => r.Deleted != true).ToList();
                return list.Select(r => EntityHelper.GetRoleEntity(r)).ToList();
            }
        }


        /// <summary>
        /// Возвращает Роль
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public RoleEntity GetRoleEntity(int currentUserId, int roleId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var role = dbcontext.Role.Where(r => r.Id == roleId && r.Deleted != true).FirstOrDefault();
                return EntityHelper.GetRoleEntity(role);
            }
        }


        /// <summary>
        /// Сохранение Роли со всеми правами доступа
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="role"></param>
        /// <returns></returns>
        public int SaveRoleEntity(int currentUserId, RoleEntity roleEntity)
        {
            using (var dbcontext = CreateDataContext())
            {
                int roleId = 0;
                Role savedRole = null;
                if (roleEntity.Role.Id > 0) // Если происходит обновление уже существующей записи с Ролью в БД
                {
                    var role = dbcontext.Role.Where(r => r.Id == roleEntity.Role.Id).FirstOrDefault();
                    if (role != null)
                    {
                        savedRole = role;

                        int pid = dbcontext.Permission.Select(p => p.Id).Max() + 1;

                        #region // Сохранение списка пунктов Меню

                        var permissionMenu = role.Permission.Where(p => p.CategoryId == (int)PermissionCategoryEnum.Menu).FirstOrDefault();
                        if (permissionMenu == null)
                        {
                            permissionMenu = new Permission()
                            {
                                Id = pid,
                                Name = string.Format("Доступные для роли '{0}' пункты меню", roleEntity.Role.Name),
                                CategoryId = (int)PermissionCategoryEnum.Menu,
                                Menu = new System.Data.Objects.DataClasses.EntityCollection<Menu>()
                            };
                            savedRole.Permission.Add(permissionMenu);
                        }
                        if (permissionMenu.Menu != null)
                        {
                            permissionMenu.Menu.Clear();
                            var menuIds = roleEntity.Menus.Select(m => m.Id).ToList();
                            var menus = dbcontext.Menu.Where(m => menuIds.Contains(m.Id)).ToList();
                            if (menus != null && menus.Count > 0)
                                foreach (var menu in menus)
                                    permissionMenu.Menu.Add(menu);
                        }

                        #endregion // Сохранение списка пунктов Меню

                        #region // Сохранение списка Статусов

                        var permissionState = role.Permission.Where(p => p.CategoryId == (int)PermissionCategoryEnum.State).FirstOrDefault();
                        if (permissionState == null)
                        {
                            pid += 1;
                            permissionState = new Permission()
                            {
                                Id = pid,
                                Name = string.Format("Доступные для смены ролью '{0}' статусы", roleEntity.Role.Name),
                                CategoryId = (int)PermissionCategoryEnum.State,
                                State = new System.Data.Objects.DataClasses.EntityCollection<State>()
                            };
                            savedRole.Permission.Add(permissionState);
                        }
                        if (permissionState.State != null)
                        {
                            permissionState.State.Clear();
                            var stateIds = roleEntity.States.Select(s => s.Id).ToList();
                            var states = dbcontext.State.Where(s => stateIds.Contains(s.Id)).ToList();
                            if (states != null && states.Count > 0)
                                foreach (var state in states)
                                    permissionState.State.Add(state);
                        }

                        #endregion // Сохранение списка Статусов

                        #region // Сохранение списка Страниц

                        var permissionWebPage = role.Permission.Where(p => p.CategoryId == (int)PermissionCategoryEnum.WebPage).FirstOrDefault();
                        if (permissionWebPage == null)
                        {
                            pid += 1;
                            permissionWebPage = new Permission()
                            {
                                Id = pid,
                                Name = string.Format("Доступные для роли '{0}' страницы системы", roleEntity.Role.Name),
                                CategoryId = (int)PermissionCategoryEnum.WebPage,
                                WebPage = new System.Data.Objects.DataClasses.EntityCollection<WebPage>()
                            };
                            savedRole.Permission.Add(permissionWebPage);
                        }
                        if (permissionWebPage.WebPage != null)
                        {
                            permissionWebPage.WebPage.Clear();
                            var webPageIds = roleEntity.WebPages.Select(w => w.Id).ToList();
                            var webPages = dbcontext.WebPage.Where(w => webPageIds.Contains(w.Id)).ToList();
                            if (webPages != null && webPages.Count > 0)
                                foreach (var webPage in webPages)
                                    permissionWebPage.WebPage.Add(webPage);
                        }

                        #endregion // Сохранение списка Страниц

                        savedRole.Name = roleEntity.Role.Name;
                        savedRole.OnlyIts = roleEntity.Role.OnlyIts;
                    }
                    else // Роль создается
                    {
                        #region // Роль создается

                        int id = dbcontext.Role.Select(r => r.Id).Max() + 1;
                        savedRole = new Role()
                        {
                            Id = id,
                            Name = roleEntity.Role.Name,
                            OnlyIts = roleEntity.Role.OnlyIts
                        };

                        #region // Сохранение списка пунктов Меню

                        int pid = dbcontext.Permission.Select(p => p.Id).Max() + 1;
                        Permission newPermissionMenu = new Permission()
                        {
                            Id = pid,
                            Name = string.Format("Доступные для роли '{0}' пункты меню", roleEntity.Role.Name),
                            CategoryId = (int)PermissionCategoryEnum.Menu
                        };
                        var menuIds = roleEntity.Menus.Select(m => m.Id).ToList();
                        var menus = dbcontext.Menu.Where(m => menuIds.Contains(m.Id)).ToList();
                        if (menus != null && menus.Count > 0)
                            foreach (var menu in menus)
                                newPermissionMenu.Menu.Add(menu);

                        savedRole.Permission.Add(newPermissionMenu);

                        #endregion // Сохранение списка пунктов Меню

                        #region // Сохранение списка Статусов

                        pid += 1;
                        Permission newPermissionState = new Permission()
                        {
                            Id = pid,
                            Name = string.Format("Доступные для смены ролью '{0}' статусы", roleEntity.Role.Name),
                            CategoryId = (int)PermissionCategoryEnum.State
                        };
                        var stateIds = roleEntity.States.Select(s => s.Id).ToList();
                        var states = dbcontext.State.Where(s => stateIds.Contains(s.Id)).ToList();
                        if (states != null && states.Count > 0)
                            foreach (var state in states)
                                newPermissionState.State.Add(state);

                        savedRole.Permission.Add(newPermissionState);

                        #endregion // Сохранение списка Статусов

                        #region // Сохранение списка Страниц

                        pid += 1;
                        Permission newPermissionWebPage = new Permission()
                        {
                            Id = pid,
                            Name = string.Format("Доступные для роли '{0}' страницы системы", roleEntity.Role.Name),
                            CategoryId = (int)PermissionCategoryEnum.WebPage
                        };
                        var webPageIds = roleEntity.WebPages.Select(w => w.Id).ToList();
                        var webPages = dbcontext.WebPage.Where(w => webPageIds.Contains(w.Id)).ToList();
                        if (webPages != null && webPages.Count > 0)
                            foreach (var webPage in webPages)
                                newPermissionWebPage.WebPage.Add(webPage);

                        savedRole.Permission.Add(newPermissionWebPage);

                        #endregion // Сохранение списка Страниц

                        dbcontext.AddToRole(savedRole);

                        #endregion // Роль создается
                    }
                }
                else // Если Роль создается
                {
                    #region // Если Роль создается

                    int id = dbcontext.Role.Select(r => r.Id).Max() + 1;
                    savedRole = new Role()
                    {
                        Id = id,
                        Name = roleEntity.Role.Name,
                        OnlyIts = roleEntity.Role.OnlyIts
                    };

                    #region // Сохранение списка пунктов Меню
                    
                    int pid = dbcontext.Permission.Select(p => p.Id).Max() + 1;
                    Permission newPermissionMenu = new Permission()
                    {
                        Id = pid,
                        Name = string.Format("Доступные для роли '{0}' пункты меню", roleEntity.Role.Name),
                        CategoryId = (int)PermissionCategoryEnum.Menu
                    };
                    var menuIds = roleEntity.Menus.Select(m => m.Id).ToList();
                    var menus = dbcontext.Menu.Where(m => menuIds.Contains(m.Id)).ToList();
                    if (menus != null && menus.Count > 0)
                        foreach(var menu in menus)
                            newPermissionMenu.Menu.Add(menu);
                    
                    savedRole.Permission.Add(newPermissionMenu);
                    
                    #endregion // Сохранение списка пунктов Меню

                    #region // Сохранение списка Статусов

                    pid += 1;
                    Permission newPermissionState = new Permission()
                    {
                        Id = pid,
                        Name = string.Format("Доступные для смены ролью '{0}' статусы", roleEntity.Role.Name),
                        CategoryId = (int)PermissionCategoryEnum.State
                    };
                    var stateIds = roleEntity.States.Select(s => s.Id).ToList();
                    var states = dbcontext.State.Where(s => stateIds.Contains(s.Id)).ToList();
                    if (states != null && states.Count > 0)
                        foreach (var state in states)
                            newPermissionState.State.Add(state);

                    savedRole.Permission.Add(newPermissionState);

                    #endregion // Сохранение списка Статусов

                    #region // Сохранение списка Страниц

                    pid += 1;
                    Permission newPermissionWebPage = new Permission()
                    {
                        Id = pid,
                        Name = string.Format("Доступные для роли '{0}' страницы системы", roleEntity.Role.Name),
                        CategoryId = (int)PermissionCategoryEnum.WebPage
                    };
                    var webPageIds = roleEntity.WebPages.Select(w => w.Id).ToList();
                    var webPages = dbcontext.WebPage.Where(w => webPageIds.Contains(w.Id)).ToList();
                    if (webPages != null && webPages.Count > 0)
                        foreach (var webPage in webPages)
                            newPermissionWebPage.WebPage.Add(webPage);

                    savedRole.Permission.Add(newPermissionWebPage);

                    #endregion // Сохранение списка Страниц

                    dbcontext.AddToRole(savedRole);

                    #endregion // Если Роль создается
                }

                dbcontext.SaveChanges();

                roleId = savedRole.Id;

                return roleId;
            }



        }


        /// <summary>
        /// Удаление Роли
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <param name="RoleId"></param>
        public void DeleteRole(int currentUserId, int RoleId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var role = dbcontext.Role.Where(r => r.Id == RoleId).FirstOrDefault();
                if (role != null)
                {
                    role.Deleted = true;
                    dbcontext.SaveChanges();
                }
            }
        }

        
        /// <summary>
        /// Возвращает список Ролей
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<Role> GetRoleList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.Role.Where(r => r.Deleted != true).ToList();
                return list;
            }
        }


        /// <summary>
        /// Возвращает список пунктов Меню
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<Menu> GetMenuList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.Menu.ToList();
                return list;
            }
        }


        /// <summary>
        /// Возвращает список Статусов документов
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<State> GetStateList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.State.ToList();
                return list;
            }
        }


        /// <summary>
        /// Возвращает список Страниц системы
        /// </summary>
        /// <param name="currentUserId"></param>
        /// <returns></returns>
        public List<WebPage> GetWebPageList(int currentUserId)
        {
            using (var dbcontext = CreateDataContext())
            {
                var list = dbcontext.WebPage.ToList();
                return list;
            }
        }


        #endregion Методы работы с объектами, относящимися к правам доступа
    }
}
